﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using Noris.Tools.TraceVisualiser.Support;

namespace Noris.Tools.TraceVisualiser.Parser
{
    #region class ParserDefaultSetting : Generátor settingů pro obecný parser pro různé konkrétní jazyky.
    /// <summary>
    /// ParserDefaultSetting : Generátor settingů pro různé konkrétní jazyky.
    /// </summary>
    public static class ParserDefaultSetting
    {
        #region Public static property, které vracejí settings
        /// <summary>
        /// ParserSetting pro Microsoft T-SQL
        /// </summary>
        public static ParserSetting MsSql { get { return _GetSettingMsSql(); } }
        #endregion
        #region Konstanty
        public const string SQL_ = "Sql";
        public const string SQL_CODE = "SqlCode";
        public const string SQL_LITERAL = "SqlLiteral";
        public const string SQL_SYSNAME = "SqlSysName";
        public const string SQL_PARENTHESIS = "SqlParenthesis";
        public const string SQL_COMMENTLINE = "SqlCommentLine";
        public const string SQL_COMMENTBLOCK = "SqlCommentBlock";
        #endregion
        #region Generátor settings pro MsSql
        private static ParserSetting _GetSettingMsSql()
        {
			ParserSetting setting = new ParserSetting("MsSql", SQL_CODE);
            AddSettingMsSql(setting);
            return setting;
        }
        /// <summary>
        /// Do daného settingu vloží položky (definice segmentů) pro jazyk T-SQL.
        /// Vrací root segment této definice.
        /// </summary>
        /// <param name="setting"></param>
        public static ParserSegmentSetting AddSettingMsSql(ParserSetting setting)
        {
            ParserSegmentSetting segment;
            ParserSegmentSetting result;

            // Společná data pro SQL_CODE a SQL_PARENTHESIS, které obě mohou obsahovat SQL kód:
            string[] blanks = new string[] { " ", "\t", "\r", "\n" };
            string[] delimiters = new string[] { ",", "+", "-", "*", "/", "<", "=", ">", "<=", ">=", "<>", "%" };

            // SQL Kód:
            segment = new ParserSegmentSetting(SQL_CODE);
            segment.Blanks = blanks.ToArray();
            segment.Delimiters = delimiters.ToArray();
            segment.EndWith = new string[] { ";" };
            segment.InnerSegmentsNames = new string[] { SQL_LITERAL, SQL_SYSNAME, SQL_PARENTHESIS, SQL_COMMENTLINE, SQL_COMMENTBLOCK };
            segment.AddRtfCodes(ParserSegmentValueType.Text,
                                new RtfItem[] { RtfItem.NewForeColor(Color.DarkGreen), RtfItem.NewFont("Courier New CE"), RtfItem.NewFontStyle(RtfFontStyle.Regular) },
                                null);
            segment.AddRtfCodes(ParserSegmentValueType.Delimiter,
                                new RtfItem[] { RtfItem.NewForeColor(Color.Magenta) },
                                new RtfItem[] { RtfItem.NewForeColor(Color.DarkGreen) });
            segment.AddRtfCodes("Keyword",
                                new RtfItem[] { RtfItem.NewForeColor(Color.MediumBlue) },
                                new RtfItem[] { RtfItem.NewForeColor(Color.DarkGreen) });
            setting.SegmentSettingAdd(segment);
            result = segment;                         // Výstup této metody

            // Stringy:
            segment = new ParserSegmentSetting(SQL_LITERAL);
            segment.BeginWith = "'";
            segment.EndWith = new string[] { "'" };
            segment.SpecialTexts = new ParserSegmentSpecialTexts[] { new ParserSegmentSpecialTexts("''", "'") };
            segment.AddRtfCodes(ParserSegmentValueType.Text,
                                new RtfItem[] { RtfItem.NewForeColor(Color.Red), RtfItem.NewFont("Courier New CE"), RtfItem.NewFontStyle(RtfFontStyle.BoldOnly) },
                                new RtfItem[] { RtfItem.NewForeColor(Color.Empty) });
            setting.SegmentSettingAdd(segment);

            // Hranaté závorky = systémové jméno:
            segment = new ParserSegmentSetting(SQL_SYSNAME);
            segment.BeginWith = "[";
            segment.EndWith = new string[] { "]" };
            segment.AddRtfCodes(ParserSegmentValueType.Text,
                                new RtfItem[] { RtfItem.NewForeColor(Color.DarkSlateGray), RtfItem.NewFont("Courier New CE"), RtfItem.NewFontStyle(RtfFontStyle.Regular) },
                                new RtfItem[] { RtfItem.NewForeColor(Color.Empty) });
            setting.SegmentSettingAdd(segment);

            // Kulaté závorky = funkce, výrazy, a pozor => i vnořené selecty, takže má charakter i code:
            segment = new ParserSegmentSetting(SQL_PARENTHESIS);
            segment.BeginWith = "(";
            segment.Blanks = blanks.ToArray();
            segment.Delimiters = delimiters.ToArray();
			segment.EndWith = new string[] { ")" };
            segment.InnerSegmentsNames = new string[] { SQL_LITERAL, SQL_SYSNAME, SQL_PARENTHESIS, SQL_COMMENTLINE, SQL_COMMENTBLOCK };
            segment.AddRtfCodes(ParserSegmentValueType.Text,
                                new RtfItem[] { RtfItem.NewForeColor(Color.DarkSlateBlue), RtfItem.NewFont("Courier New CE"), RtfItem.NewFontStyle(RtfFontStyle.Regular) },
                                new RtfItem[] { RtfItem.NewForeColor(Color.Empty) });
            segment.AddRtfCodes("Keyword",
                                new RtfItem[] { RtfItem.NewForeColor(Color.MediumBlue) },
                                new RtfItem[] { RtfItem.NewForeColor(Color.DarkGreen) });
            segment.AddRtfCodes(ParserSegmentValueType.Delimiter,
                                new RtfItem[] { RtfItem.NewForeColor(Color.Magenta) },
                                new RtfItem[] { RtfItem.NewForeColor(Color.DarkSlateBlue) });
            setting.SegmentSettingAdd(segment);

            // Komentář řádkový (začíná --, končí koncem řádku, přičemž konec není ukládán do segmentu, ale zpracuje se jako další text):
            segment = new ParserSegmentSetting(SQL_COMMENTLINE);
            segment.BeginWith = "--";
            segment.EndWith = new string[] { "\r\n", "\r", "\n" };
            segment.EndOutside = true;
            segment.AddRtfCodes(ParserSegmentValueType.Text,
                                new RtfItem[] { RtfItem.NewForeColor(Color.DarkSlateGray), RtfItem.NewFont("Courier New CE"), RtfItem.NewFontStyle(RtfFontStyle.Regular), RtfItem.NewHighlight(Color.FromArgb(226, 226, 234)) },
                                new RtfItem[] { RtfItem.NewForeColor(Color.Empty), RtfItem.NewHighlight(Color.Empty) });
            setting.SegmentSettingAdd(segment);

            // Komentář blokový (začíná /*, končí */), otázka je zda může obsahovat vnořené blokové komentáře => rozhodnutí zní ANO:
            segment = new ParserSegmentSetting(SQL_COMMENTBLOCK);
            segment.BeginWith = "/*";
            segment.EndWith = new string[] { "*/" };
			segment.InnerSegmentsNames = new string[] { SQL_COMMENTBLOCK };
            segment.AddRtfCodes(ParserSegmentValueType.Text,
                                new RtfItem[] { RtfItem.NewForeColor(Color.DarkSlateGray), RtfItem.NewFont("Courier New CE"), RtfItem.NewFontStyle(RtfFontStyle.Regular), RtfItem.NewHighlight(Color.FromArgb(226, 226, 234)) },
                                new RtfItem[] { RtfItem.NewForeColor(Color.Empty), RtfItem.NewHighlight(Color.Empty) });
            setting.SegmentSettingAdd(segment);

            // Vrátíme segment, který je rootem této entity
            return result;
        }
        #endregion
	}
    #endregion
}
